package droid.frame.utils.lang;

import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.text.Editable;
import android.text.Selection;
import android.text.TextUtils;
import android.widget.EditText;
import android.widget.TextView;

import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;

public class Str {

    /**
     * 支持str|CharSequence等数据类型
     *
     * @param str
     * @return
     */
    public static boolean isEmpty(Object str) {
        return str == null || str.toString().trim().length() == 0 || "null".equals(str.toString().trim());
    }

    public static boolean isNotEmpty(Object str) {
        return !isEmpty(str);
    }

    /**
     * 将Str转化成int防止转型失败导致的崩溃
     *
     * @param str
     * @return
     */
    public static int parseInt(String str) {
        try {
            // 如果传入11.0等浮点型, 保证不致于出错
            float f = Float.valueOf(str);
            int result = (int) f;
            return result;
        } catch (NumberFormatException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return 0;
    }

    /**
     * 将Str转化成float防止转型失败导致的崩溃
     *
     * @param str
     * @return
     */
    public static float parseFloat(String str) {
        try {
            if (isNotEmpty(str) && !"null".equals(str)) {
                float result = Float.valueOf(str);
                return result;
            }
        } catch (NumberFormatException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return 0;
    }

    /**
     * 格式化成带两位小数点
     *
     * @param price
     * @return
     */
    public static String formatPrice(String price) {
        if (Str.isEmpty(price)) {
            return "";
        } else {
            if (price.contains(".")) {
                int index = price.indexOf(".");
                // 0.1
                if (index == price.length() - 2) {// 小数点是倒数第二个
                    price += "0";
                }
                // 0.
                else if (index == price.length() - 1) {// 倒数第一个
                    price += "00";
                }
            } else {
                price += ".00";
            }
            return price;
        }
    }

    /**
     * 返回不带空格的手机号
     *
     * @param phoneNum
     * @return
     */
    public static String formatPhone(String phoneNum) {
        String phoneCode = phoneNum;
        // 小米等设备--返回到的数据带有空格
        // 152 1078 8660
        phoneCode = phoneCode.replace("+86", "").replace("+", "");
        // 过滤掉非数字的字符
        for (int i = 0; i < phoneCode.length(); i++) {
            char ch = phoneCode.charAt(i);
            if (ch < '0' || ch > '9') {
                phoneCode = phoneCode.replace(ch + "", " ");
            }
        }
        phoneCode = phoneCode.replace(" ", "");
        // phoneName = phoneName.replace(" ", "");
        phoneCode = phoneCode.trim();
        return phoneCode;
    }

    /**
     * 格式化手机号, 或者投递袋编号
     *
     * @param editable
     * @param segs     在指定的位置插入空格 例如:123 45 6789,传入参数 3,5 返回123 45 6789<br>
     */
    public static void format(Editable editable, int... segs) {
        String oldStr = editable.toString();
        //
        StringBuilder newStr = new StringBuilder(oldStr.replace(" ", ""));
        // 从后面开始插入
        for (int i = segs.length - 1; i >= 0; i--) {
            // 要插入空格的位置
            int position = segs[i];
            if (newStr.length() > position) {
                newStr.insert(position, ' ');
            }
        }
        // 如果oldStr被修改了
        if (newStr.toString().equals(editable.toString()) == false) {
            // editable改变以后会继续回调 #afterTextChanged
            editable.replace(0, editable.length(), newStr.toString());
        }
    }

    /**
     * 根据参数格式化<br>
     * 10位 111 111 1111<br>
     *
     * @param bagCode 参数类型定义为TextView <br>
     *                因为 EditText extends TextView
     */
    public static String formatBagCode(TextView bagCode) {
        String result = strFormatByEmpty(bagCode.getText().toString(), true, 2, 3);
        bagCode.setText(result);
        // 光标后移
        if (bagCode instanceof EditText) {
            Editable editable = bagCode.getEditableText();
            Selection.setSelection(editable, editable.length());
        }
        return result;
    }

    /**
     * 格式化字符串
     *
     * @param group 要分多少组（不包含最后一组）
     * @param count 一组多少个数
     * @param str   要分组的字符串
     * @param front true从前面开始，否则从后面
     * @return 返回格式化后的数据
     */
    public static String strFormatByEmpty(String str, boolean front, int group, int count) {
        if (count < 1) {
            return "";
        }
        StringBuilder sb = new StringBuilder();
        // 格式化前先清理空字符
        str = strClearEmpty(str);
        int len = str.length();
        // 满个数的组数
        int groupNum = len / count;
        // 从前面截断 1386 1650 896
        if (front) {
            // 先处理满个数的组
            for (int i = 0; i < groupNum && i < group; i++) {
                String subStr = str.substring(i * count, (i + 1) * count);
                sb.append(subStr);
                // 防止截取的字符串刚好等于str的长度再添加空字符
                if ((i + 1) * count != len) {
                    sb.append(" ");
                }
            }
            // 超出group的字符串都设为一组
            if (groupNum >= group) {
                sb.append(str.substring(group * count, len));
                // 在group内不够count的字符串都设为一组
            } else if (groupNum * count < len) {
                sb.append(str.substring((groupNum) * count, len));
            }
        } else {
            // 从后面截 138 6165 0896
            for (int i = 0; i < groupNum && i < group; i++) {
                String subStr = str.substring(len - (i + 1) * count, len - i * count);
                sb.insert(0, subStr);
                if ((i + 1) * count != len) {
                    sb.insert(0, " ");
                }
            }
            if (groupNum >= group) {
                sb.insert(0, str.substring(0, len - group * count));
            } else if (groupNum * count < len) { // 在group内不够count的字符串都设为一组
                sb.insert(0, str.substring(0, len - groupNum * count));
            }
        }
        return sb.toString();
    }

    /**
     * @param str 要去空格的字符串
     * @return
     */
    public static String strClearEmpty(String str) {
        if (str == null) {
            return "";
        }
        str = str.replace(" ", "");
        return str;
    }

    /**
     * @param number
     * @return
     * @Title : filterNumber
     * @Type : FilterStr
     * @Description : 过滤出数字
     */
    public static String filterNumber(String number) {
        if (isNotEmpty(number)) {
            number = number.replaceAll("[^(0-9)]", "");
            return number;
        } else {
            return "";
        }
    }

    /**
     * @param alph
     * @return
     * @Title : filterAlphabet
     * @Type : FilterStr
     * @Description : 过滤出字母
     */
    public static String filterAlphabet(String alph) {
        if (isNotEmpty(alph)) {
            alph = alph.replaceAll("[^(A-Za-z)]", "");
            return alph;
        } else {
            return "";
        }
    }

    /**
     * @param chin
     * @return
     * @Title : filterChinese
     * @Type : FilterStr
     * @Description : 过滤出中文
     */
    public static String filterChinese(String chin) {
        if (isNotEmpty(chin)) {
            chin = chin.replaceAll("[^(\\u4e00-\\u9fa5)]", "");
            return chin;
        } else {
            return "";
        }
    }

    /**
     * @param character
     * @return
     * @Title : filter
     * @Type : FilterStr
     * @Description : 过滤出字母、数字和中文
     */
    public static String filter(String character) {
        if (isNotEmpty(character)) {
            character = character.replaceAll("[^(a-zA-Z0-9\\u4e00-\\u9fa5)]", "");
            return character;
        } else {
            return "";
        }

    }
    /**
     * @param character
     * @return
     * @Title : filter
     * @Type : FilterStr
     * @Description : 过滤出字母、数字、中文和逗号
     */
    public static String filterEditText(String character) {
        if (isNotEmpty(character)) {
            character = character.replaceAll("[^(a-zA-Z0-9\\u4e00-\\u9fa5;,，；)]", "");
            return character;
        } else {
            return "";
        }

    }

    /**
     * 获取在标签下的渠道号
     *
     * @param context 当前环境
     * @return 渠道号
     */
    public static String getChannel(Context context) {
        String gameChannel = getManifestMeta(context, "gs_channel");
        if (TextUtils.isEmpty(gameChannel)) {
            gameChannel = "android";
        }
        return gameChannel;
    }

    /**
     * 获取manifest中的meta信息
     *
     * @param context 当前的环境
     * @param key     需要去meta信息的key
     * @return 获取到的meta信息
     */
    public static String getManifestMeta(Context context, String key) {
        String result;
        try {
            ApplicationInfo appInfo = context.getPackageManager()
                    .getApplicationInfo(context.getPackageName(), PackageManager.GET_META_DATA);

            result = appInfo.metaData.get(key) + "";
        } catch (Exception e) {
            return "";
        }
        if (TextUtils.isEmpty(result)) {
            return "";
        }
        return result;
    }

    /**
     * 将数据进行格式化显示
     *
     * @param data 需要格式化的数据
     * @return 格式化后的数据
     */
    public static String formatDoubleData(Double data) {
        final DecimalFormat df = new DecimalFormat("###.##");
        return df.format(data);
    }

    /**
     * 将double格式化为指定小数位的String，不足小数位用0补全
     *
     * @param v     需要格式化的数字
     * @param scale 小数点后保留几位
     * @return
     */
    public static String roundByScale(double v, int scale) {
        if (scale < 0) {
            scale = 0;
        }
        if (scale == 0) {
            return new DecimalFormat("0").format(v);
        }
        String formatStr = "0.";
        for (int i = 0; i < scale; i++) {
            formatStr = formatStr + "0";
        }
        return new DecimalFormat(formatStr).format(v);
    }

    public static String formatVideoTime(int second) {
        StringBuffer stringBuffer = new StringBuffer();
        DecimalFormat decimalFormat = new DecimalFormat("00");
        if ((second / (60 * 60)) > 0) {
            stringBuffer.append(second / (60 * 60) + ":");
        }
        if ((second % (60 * 60) / 60) >= 0) {
            stringBuffer.append(decimalFormat.format(second % (60 * 60) / 60) + ":");//分
        }
        if (second % 60 >= 0) {
            stringBuffer.append(decimalFormat.format(second % 60));
        }
        return stringBuffer.toString();
    }

    public static String formatHHmmNormalTime(int second) {
        StringBuffer stringBuffer = new StringBuffer();
        DecimalFormat decimalFormat = new DecimalFormat("00");
        if ((second / (60 * 60)) > 0) {
            stringBuffer.append(second / (60 * 60) + ":");
        } else {
            stringBuffer.append("00:");
        }
        if ((second % (60 * 60) / 60) >= 0) {
            stringBuffer.append(decimalFormat.format(second % (60 * 60) / 60));//分
        } else {
            stringBuffer.append("00");
        }
        return stringBuffer.toString();
    }

    /**
     * 秒转换成0.0小时
     */
    public static String formatHHmmTime(int second) {
        StringBuffer stringBuffer = new StringBuffer();
        DecimalFormat decimalFormat = new DecimalFormat("00");
        if (second % 60 > 0) {
            second += 60;
        }
        if ((second / (60 * 60)) > 0) {
            stringBuffer.append(second / (60 * 60) + ":");
        } else {
            stringBuffer.append("00:");
        }
        if ((second % (60 * 60) / 60) >= 0) {
            stringBuffer.append(decimalFormat.format(second % (60 * 60) / 60));//分
        } else {
            stringBuffer.append("00");
        }
        return stringBuffer.toString();
    }

    public static String formatHHmmssTime(int second) {
        StringBuffer stringBuffer = new StringBuffer();
        DecimalFormat decimalFormat = new DecimalFormat("00");
        //时
        if ((second / (60 * 60)) > 0) {
            stringBuffer.append(second / (60 * 60) + ":");
        } else {
            stringBuffer.append("00:");
        }
        if ((second % (60 * 60) / 60) >= 0) {
            stringBuffer.append(decimalFormat.format(second % (60 * 60) / 60) + ":");//分
        } else {
            stringBuffer.append("00:");
        }
        //秒
        if (second % 60 >= 0) {
            stringBuffer.append(decimalFormat.format(second % 60));
        } else {
            stringBuffer.append("00");
        }
        return stringBuffer.toString();
    }

    /**
     * 比较两个版本的大小
     *
     * @param currentVersion 本地版本号
     * @param lastesVersion  服务器版本号
     * @return 下载的是否大于当前的版本，TRUE为大于需要下载，FALSE为不大于不需要更新
     */
    public static boolean compareTwoVersionNumber(String currentVersion, String lastesVersion) {
        if (TextUtils.isEmpty(currentVersion)) {
            currentVersion = "0";
        }
        if (TextUtils.isEmpty(lastesVersion)) {
            lastesVersion = "0";
        }
        final String localString = currentVersion.replaceAll("[^-+.\\d]", "");
        final String serverString = lastesVersion.replaceAll("[^-+.\\d]", "");
        final String[] s1 = serverString.split("\\.");
        final String[] s2 = localString.split("\\.");
        if (s1.length > s2.length) {
            return !compareArray(s2, s1);
        } else {
            return compareArray(s1, s2);
        }
    }

    private static boolean compareArray(final String[] s1, final String[] s2) {
        for (int i = 0; i < s1.length; i++) {
            if (Integer.valueOf(s1[i]) > Integer.valueOf(s2[i])) {
                return true;
            } else if (Integer.valueOf(s1[i]) < Integer.valueOf(s2[i])) {
                return false;
            }
        }
        return false;

    }

    /**
     * 判断是不是身份证号
     */
    public static boolean isIdentityNumber(final String idNumber) {
        Pattern p = null;
        if (idNumber.length() == 15) {
            p = Pattern.compile("^[1-9]\\d{5}\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{2}$");
        } else if (idNumber.length() == 18) {
            p = Pattern.compile("^[1-9]\\d{5}(18|19|([23]\\d))\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$");
        }
        if (p == null) {
            return false;
        } else {
            return idNumber.matches(p.toString());
        }
    }

    /**
     * 18位身份证校验,比较严格校验
     *
     * @param idCard
     * @return
     * @author lyl
     */
    private boolean is18ByteIdCardComplex(String idCard) {
        Pattern pattern1 = Pattern.compile("^(\\d{6})(19|20)(\\d{2})(1[0-2]|0[1-9])(0[1-9]|[1-2][0-9]|3[0-1])(\\d{3})(\\d|X|x)?$");
        Matcher matcher = pattern1.matcher(idCard);
        int[] prefix = new int[]{7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
        int[] suffix = new int[]{1, 0, 10, 9, 8, 7, 6, 5, 4, 3, 2};
        if (matcher.matches()) {
            Map<String, String> cityMap = initCityMap();
            if (cityMap.get(idCard.substring(0, 2)) == null) {
                return false;
            }
            int idCardWiSum = 0; //用来保存前17位各自乖以加权因子后的总和
            for (int i = 0; i < 17; i++) {
                idCardWiSum += Integer.valueOf(idCard.substring(i, i + 1)) * prefix[i];
            }

            int idCardMod = idCardWiSum % 11;//计算出校验码所在数组的位置
            String idCardLast = idCard.substring(17);//得到最后一位身份证号码

            //如果等于2，则说明校验码是10，身份证号码最后一位应该是X
            if (idCardMod == 2) {
                if (idCardLast.equalsIgnoreCase("x")) {
                    return true;
                } else {
                    return false;
                }
            } else {
                //用计算出的验证码与最后一位身份证号码匹配，如果一致，说明通过，否则是无效的身份证号码
                if (idCardLast.equals(suffix[idCardMod] + "")) {
                    return true;
                } else {
                    return false;
                }
            }
        }
        return false;
    }

    private Map<String, String> initCityMap() {
        Map<String, String> cityMap = new HashMap<String, String>();
        cityMap.put("11", "北京");
        cityMap.put("12", "天津");
        cityMap.put("13", "河北");
        cityMap.put("14", "山西");
        cityMap.put("15", "内蒙古");

        cityMap.put("21", "辽宁");
        cityMap.put("22", "吉林");
        cityMap.put("23", "黑龙江");

        cityMap.put("31", "上海");
        cityMap.put("32", "江苏");
        cityMap.put("33", "浙江");
        cityMap.put("34", "安徽");
        cityMap.put("35", "福建");
        cityMap.put("36", "江西");
        cityMap.put("37", "山东");

        cityMap.put("41", "河南");
        cityMap.put("42", "湖北");
        cityMap.put("43", "湖南");
        cityMap.put("44", "广东");
        cityMap.put("45", "广西");
        cityMap.put("46", "海南");

        cityMap.put("50", "重庆");
        cityMap.put("51", "四川");
        cityMap.put("52", "贵州");
        cityMap.put("53", "云南");
        cityMap.put("54", "西藏");

        cityMap.put("61", "陕西");
        cityMap.put("62", "甘肃");
        cityMap.put("63", "青海");
        cityMap.put("64", "宁夏");
        cityMap.put("65", "新疆");

        cityMap.put("71", "台湾");
        cityMap.put("81", "香港");
        cityMap.put("82", "澳门");
        //          cityMap.put("91", "国外");
        //          System.out.println(cityMap.keySet().size());
        return cityMap;
    }

    /**
     * 大陆号码或香港号码均可
     */
    public static boolean isPhoneLegal(String str) {
        return isChinaPhoneLegal(str) || isHKPhoneLegal(str);
    }

    /**
     * 大陆手机号码11位数，匹配格式：前三位固定格式+后8位任意数
     * 此方法中前三位格式有：
     * 13+任意数
     * 15+除4的任意数
     * 18+除1和4的任意数
     * 17+除9的任意数
     * 147
     */
    private static boolean isChinaPhoneLegal(String str) throws PatternSyntaxException {
        String regExp = "^((13[0-9])|(15[^4])|(18[0,2,3,5-9])|(17[0-8])|(147)|(16[0-9])|(19[0-9]))\\d{8}$";
        Pattern p = Pattern.compile(regExp);
        Matcher m = p.matcher(str);
        return m.matches();
    }

    /**
     * 香港手机号码8位数，5|6|8|9开头+7位任意数
     */
    private static boolean isHKPhoneLegal(String str) throws PatternSyntaxException {
        String regExp = "^(5|6|8|9)\\d{7}$";
        Pattern p = Pattern.compile(regExp);
        Matcher m = p.matcher(str);
        return m.matches();
    }

}
